﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;

namespace ConAppCore.Test
{
    internal class TestThreadEx
    {
        public static void Test()
        {

            //TestCancellationTokenWaitOne();
            //TestParallel();
            //TestParallelPer();
            //TestParallelSum();

            SetCore();
        }


        private static void SetCore()
        {
            new ThreadEx(SetCoreMethod).Start((int)1);
            //new ThreadEx(SetCoreMethod).Start((int)3);
            Console.ReadKey();
        }

        private static void SetCoreMethod(ThreadPara threadPara)
        {
            int coreID = (int)threadPara.Para;
            ThreadEx.SetThreadRunCPUCore(coreID);

            while (true)
            {

            }

        }

        private static void TestParallelSum()
        {
            var parallel = new ParalleFunc<object, object>(4, (t) => { });

            int[] arr = new int[1000];
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = i;
            }


            long sum = 0L;
            ParallelEx.ParallelExcute<int[]>(arr, 0, arr.Length, 4, null, (item) =>
            {
                long sum0 = 0L;
                for (int i = item.StartIndex; i < item.EndIndex; i++)
                {
                    sum0 += arr[i];
                }
                Interlocked.Add(ref sum, sum0);
            });


            ParalleFuncItem<int[], double>[] retItems = ParallelEx.ParallelExcute<int[], double>(arr, 0, arr.Length, 4, null, (item) =>
            {
                double sum0 = 0d;
                for (int i = item.StartIndex; i < item.EndIndex; i++)
                {
                    sum0 += arr[i];
                }
                item.Result = sum0;
            });

            var sum2 = retItems.Sum(t => { return t.Result; });



        }


        private static void TestParallelPer()
        {
            int testCount = 1000;
            int count = 10000000;
            Stopwatch stopwatch = new Stopwatch();
            List<double> segTimes = new List<double>(testCount);
            List<double> xxTimes = new List<double>(testCount);
            int[] arr = new int[count];

            for (int i = 0; i < testCount; i++)
            {
                stopwatch.Restart();
                ParallelEx.ParallelExcute(arr, 0, count, 20, null, (t) =>
                {
                    for (int i = t.BeginIndex; i < t.EndIndex; i++)
                    {
                        t.Source[i] = i;
                    }
                });
                stopwatch.Stop();
                segTimes.Add(stopwatch.Elapsed.TotalMilliseconds);
            }

            Console.WriteLine("------------------------------------");

            for (int i = 0; i < testCount; i++)
            {
                stopwatch.Restart();
                Parallel.For(0, count, (t) =>
                {
                    arr[t] = t;
                });
                stopwatch.Stop();
                xxTimes.Add(stopwatch.Elapsed.TotalMilliseconds);
            }

            //string str = string.Join(',', arr);

            double segAvg = Math.Round(segTimes.Average(), 3);
            double xxAvg = Math.Round(xxTimes.Average(), 3);
        }



        private static void TestParallel()
        {
            int[] arr = new int[10];

            //ParallelEx.ParallelExcuteNoMod(arr, 0, arr.Length, 3, null, (t) =>
            //{
            //    for (int i = t.BeginIndex; i < t.EndIndex; i++)
            //    {
            //        t.Source[i] = i;
            //    }
            //});



            ParallelEx.ParallelExcute<object>(null, 42, 5078, 8, null, (t) =>
            {
                if (t.SegId == 7)
                {

                }
            });
        }



        private static void TestCancellationTokenWaitOne()
        {
            using var sendDataIntervalToken = new CancellationTokenEx();
            //ThreadEx.InitIterations(10, 100);

            Stopwatch stopwatch = new Stopwatch();
            double ret;
            for (int i = 1; i < 50; i++)
            {
                stopwatch.Restart();
                sendDataIntervalToken.WaitOne(i);
                //ret = ThreadEx.SpinWait(i);
                stopwatch.Stop();
                Console.WriteLine($"第{i}次WaitOne时间:{stopwatch.Elapsed.TotalMilliseconds}ms");
            }

        }


    }
}
